package com.zyht.bank.wechat.utils.idcard;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wx.core.process.JEEWeiXinX509TrustManager;

/**
 * Created by LL on 2017/3/9.
 */
public class Fetcher {
	//    private final Logger logger = Logger.getLogger(Fetcher.class);
	private RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(80000).setConnectTimeout(80000)
			.build();
	private BasicCookieStore cookieStore;
	private CloseableHttpClient httpClient;
	private final String _DEFAULT_CHARSET = "UTF-8";

	public Fetcher() {
		this.cookieStore = new BasicCookieStore();;
		this.httpClient = HttpClients.createDefault();
	}
	private static void fillHeader(String url, HttpRequestBase headergroup) {
		headergroup.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 5.1; rv:29.0) Gecko/20100101 Firefox/29.0");
		headergroup.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
		headergroup.setHeader("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
		headergroup.setHeader("Accept-Encoding", "gzip, deflate");
		headergroup.setHeader("Connection", "keep-alive");
		headergroup.setHeader("Referer", url);
		headergroup.setHeader("Cache-Control", "max-age=0");
	}

	public String get(String url) {
		return get(url, _DEFAULT_CHARSET);
	}

	public String get(String url, String charset) {
		return get(url, null, charset);
	}

	public String get(String url, Map<String, String> headers, String charset) {
		HttpClientContext context = HttpClientContext.create();
		context.setCookieStore(cookieStore);
		String useCharset = charset == null ? _DEFAULT_CHARSET : charset;

		HttpGet httpGet = new HttpGet(url);
		fillHeader(url, httpGet);

		if (headers != null) {
			for (String key : headers.keySet()) {
				httpGet.setHeader(key, headers.get(key));
			}
		}

		httpGet.setConfig(requestConfig);
		try {
			CloseableHttpResponse response = httpClient.execute(httpGet, context);
			try {
				HttpEntity entity = response.getEntity();
				return EntityUtils.toString(entity, useCharset);
			} finally {
				response.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public CloseableHttpResponse post(String url, Map<String, Object> params) {
		HttpClientContext context = HttpClientContext.create();
		context.setCookieStore(cookieStore);

		try {
			HttpPost httpPost = new HttpPost(url);
			fillHeader(url, httpPost);

			putParams(params, httpPost);

			httpPost.setConfig(requestConfig);
			CloseableHttpResponse response = httpClient.execute(httpPost, context);

			return response;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	private void putParams(Map<String, Object> params, HttpPost httpPost) throws UnsupportedEncodingException {
		if (params != null) {
			List<NameValuePair> nvps = new ArrayList<>();
			for (String key : params.keySet()) {
				nvps.add(new BasicNameValuePair(key, String.valueOf(params.get(key))));
			}
			httpPost.setEntity(new UrlEncodedFormEntity(nvps, _DEFAULT_CHARSET));
		}
	}

	public String post(String url, Map<String, Object> params, Map<String, String> headers, String charset) {
		HttpClientContext context = HttpClientContext.create();
		context.setCookieStore(cookieStore);
		String useCharset = charset == null ? _DEFAULT_CHARSET : charset;

		try {
			HttpPost httpPost = new HttpPost(url);
			fillHeader(url, httpPost);
			if (headers != null) {
				for (String key : headers.keySet()) {
					httpPost.setHeader(key, headers.get(key));
				}
			}

			putParams(params, httpPost);

			httpPost.setConfig(requestConfig);
			CloseableHttpResponse response = httpClient.execute(httpPost, context);
			try {
				HttpEntity entity = response.getEntity();
				if (entity != null) {
					if (response.getStatusLine().getStatusCode() == 200) {
						return EntityUtils.toString(entity, useCharset);
					} else {
						return null;
					}
				}
			} finally {
				response.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// 发送请求
	public JSONObject httpsRequest(String requestUrl, String requestMethod, String json) {
		return JSON.parseObject(httpsRequestStr(requestUrl, requestMethod, json));
	}

	public String httpsRequestStr(String requestUrl, String requestMethod, String json) {

		try {
			TrustManager[] tm = {new JEEWeiXinX509TrustManager()};
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			SSLSocketFactory ssf = sslContext.getSocketFactory();

			URL url = new URL(requestUrl);
			HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
			conn.setSSLSocketFactory(ssf);
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);
			conn.setRequestMethod(requestMethod);
			if (null != json) {
				OutputStream outputStream = conn.getOutputStream();
				outputStream.write(json.getBytes(_DEFAULT_CHARSET));
				outputStream.close();
			}
			InputStream inputStream = conn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream, _DEFAULT_CHARSET);
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			String str;
			StringBuffer buffer = new StringBuffer();
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			bufferedReader.close();
			inputStreamReader.close();
			inputStream.close();
			conn.disconnect();
			return buffer.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}


}